package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"regexp"
	"strconv"
	"time"
)

const (
	SearchResultUrl  = "http://114.163.com/search/1/904/?q=&s=10&from=pager&p=%s"
	CompanyDetailUrl = "http://114.163.com%s"
)

func main() {
	// init
	resultNumber := 1
	reg, err := regexp.Compile(`/company/\d+`)
	if err != nil {
		log.Fatalln("regexp failed, message:", err)
	}

	// get company url
	var urls []string
	for i := 0; i < resultNumber; i++ {
		urls = append(urls, fmt.Sprintf(SearchResultUrl, strconv.FormatInt(int64(i), 10)))
	}
	regMap := make(map[string]*regexp.Regexp)
	regMap["url"] = reg
	result, _ := Find(urls, regMap, time.Millisecond*100, true)

	// delete Duplicate information
	urlMap := make(map[string]bool)
	for _, value := range result {
		urls := value["url"]
		for _, url := range urls {
			urlMap[url] = false
		}
	}

	log.Printf("get %d urls.\n", len(urlMap))
	urls = []string{}
	for key, _ := range urlMap {
		urls = append(urls, fmt.Sprintf(CompanyDetailUrl, key))
	}

	regMap = make(map[string]*regexp.Regexp)
	regMap["name"], _ = regexp.Compile("name")
	regMap["phone"], _ = regexp.Compile(`\d{4}-\d{8}`)
	regMap["email"], _ = regexp.Compile("email")
	regMap["website"], _ = regexp.Compile("website")
	result, _ = Find(urls, regMap, time.Millisecond*100, true)

	for _, value := range result {
		fmt.Println(value["phone"])
	}
}

func Find(urls []string, regMap map[string]*regexp.Regexp, duration time.Duration, ingnore bool) ([]map[string][]string, error) {
	var result []map[string][]string

	for _, url := range urls {
		page, err := GetPage(url)
		if err != nil {
			if ingnore {
				log.Print(url, err)
				continue
			} else {
				return nil, err
			}
		}
		for key, value := range regMap {
			m := make(map[string][]string)
			m[key] = value.FindAllString(page, -1)
			result = append(result, m)
		}
		time.Sleep(duration)
	}
	return result, nil
}

func printStringArray(strs []string) {
	for index, value := range strs {
		fmt.Printf("%d, %s\n", index+1, value)
	}
}

func GetPage(url string) (string, error) {
	log.Println("get url:", url)
	resp, err := http.Get(url)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	bs, err := ioutil.ReadAll(resp.Body)
	return string(bs), err
}
